package lin

import (
	"sort"
	"strings"
	"unicode/utf8"
)

type W文本 struct {
}

func (*W文本) X寻找文本(原始文本, 寻找文本 string) (位置 int) {
	位置 = strings.Index(原始文本, 寻找文本)
	if 位置 == -1 {
		return
	}
	实际文本 := 原始文本[:位置]
	return utf8.RuneCountInString(实际文本)
}

func (*W文本) X寻找文本位置组_正向找(原始文本, 寻找文本 string) (返回_值 []int) {
	次数 := strings.Count(原始文本, 寻找文本)
	位置 := 0
	累计位置 := 0
	for i := 0; i < 次数; i++ {
		位置 = strings.Index(原始文本, 寻找文本)

		if 位置 < 0 {
			return
		}
		实际文本 := 原始文本[:位置]
		原始文本 = 原始文本[位置+len(寻找文本):]
		位置 = utf8.RuneCountInString(实际文本)
		累计位置 = 累计位置 + 位置
		if i > 0 {
			累计位置 = 累计位置 + utf8.RuneCountInString(寻找文本)
		}
		返回_值 = append(返回_值, 累计位置)
	}
	return
}
func (*W文本) X寻找文本位置组_逆向找(原始文本, 寻找文本 string) (返回_值 []int) {
	次数 := strings.Count(原始文本, 寻找文本)
	位置 := 0
	累计位置 := 0
	for i := 0; i < 次数; i++ {
		位置 = strings.Index(原始文本, 寻找文本)

		if 位置 < 0 {
			return
		}
		实际文本 := 原始文本[:位置]
		原始文本 = 原始文本[位置+len(寻找文本):]
		位置 = utf8.RuneCountInString(实际文本)
		累计位置 = 累计位置 + 位置
		if i > 0 {
			累计位置 = 累计位置 + utf8.RuneCountInString(寻找文本)
		}
		返回_值 = append(返回_值, 累计位置)
	}
	sort.Slice(返回_值, func(i, j int) bool {
		return 返回_值[j] < 返回_值[i]
	})

	return
}

// @返回字符串 原始文本 中字符串  寻找文本 最后一次出现的位置
func (*W文本) X寻找文本_倒找(原始文本, 寻找文本 string) (位置 int) {
	位置 = strings.LastIndex(原始文本, 寻找文本)
	if 位置 == -1 {
		return
	}
	实际文本 := 原始文本[:位置]
	return utf8.RuneCountInString(实际文本)
}

//	文本_取左边/
//
// @原始文本 被取的文本
// @寻找文本 关键词
// @启始寻找位置  <0 为 从右往左边 -1 默认最高后一个 其他按位置范围
func (类 *W文本) QZ取左边(原始文本, 寻找文本 string, 启始位置 ...int) (结果 string) {

	启始寻找位置 := 0

	if len(启始位置) > 0 {
		启始寻找位置 = 启始位置[0]
	}
	if 启始寻找位置 < 0 {
		启始寻找位置 = utf8.RuneCountInString(原始文本) + 启始寻找位置
	}

	if 启始寻找位置 >= utf8.RuneCountInString(原始文本) || 启始寻找位置 < 0 {
		return
	}
	次数 := strings.Count(原始文本, 寻找文本)
	位置 := 0
	累计位置 := 0
	结果文本 := ""
	for i := 0; i < 次数; i++ {
		位置 = strings.Index(原始文本, 寻找文本)

		if 位置 < 0 {
			return
		}
		实际文本 := 原始文本[:位置]
		原始文本 = 原始文本[位置+len(寻找文本):]
		位置 = utf8.RuneCountInString(实际文本)
		累计位置 = 累计位置 + 位置
		if i > 0 {
			累计位置 = 累计位置 + utf8.RuneCountInString(寻找文本)
		}

		if i > 0 {
			结果文本 = 结果文本 + 寻找文本 + 实际文本
		} else {
			结果文本 = 结果文本 + 实际文本
		}
		if 累计位置 >= 启始寻找位置 {
			return 结果文本
		}
		if 启始位置[0] == -1 && i == 次数-1 {
			return 结果文本
		}
	}

	return

}
func (类 *W文本) QZ取左边_按字符数(原始文本 string, 取出数 int) (返回文本 string) {
	返回文本 = ""
	i := 0
	for _, v := range 原始文本 {
		if i < 取出数 {
			返回文本 = 返回文本 + string(v)
		}
		i++
	}
	return

}

//	文本_取右边
//
// @原始文本 被取的文本
// @寻找文本 关键词
// @启始寻找位置  <0 为 从右往左边 -1 默认最高后一个 其他按位置范围
func (类 *W文本) QY取右边(原始文本, 寻找文本 string, 启始位置 ...int) (结果 string) {
	初文本 := 原始文本
	启始寻找位置 := 0

	if len(启始位置) > 0 {
		启始寻找位置 = 启始位置[0]
	}
	if 启始寻找位置 < 0 {
		启始寻找位置 = utf8.RuneCountInString(原始文本) + 启始寻找位置
	}

	if 启始寻找位置 >= utf8.RuneCountInString(原始文本) || 启始寻找位置 < 0 {
		return
	}
	次数 := strings.Count(原始文本, 寻找文本)
	位置 := 0
	累计位置 := 0
	结果文本 := ""
	for i := 0; i < 次数; i++ {
		位置 = strings.Index(原始文本, 寻找文本)

		if 位置 < 0 {
			return
		}
		实际文本 := 原始文本[:位置]
		原始文本 = 原始文本[位置+len(寻找文本):]
		位置 = utf8.RuneCountInString(实际文本)
		累计位置 = 累计位置 + 位置
		if i > 0 {
			累计位置 = 累计位置 + utf8.RuneCountInString(寻找文本)
		}

		if i > 0 {
			结果文本 = 结果文本 + 寻找文本 + 实际文本
		} else {
			结果文本 = 结果文本 + 实际文本
		}
		if 累计位置 >= 启始寻找位置 {
			结果文本 = 初文本[len(结果文本)+len(寻找文本):]
			return 结果文本
		}
		if 启始位置[0] == -1 && i == 次数-1 {
			结果文本 = 初文本[len(结果文本)+len(寻找文本):]
			return 结果文本
		}
	}

	return

}

func (类 *W文本) QY取右边_按字符数(原始文本 string, 取出数 int) (返回文本 string) {
	返回文本 = ""
	长度 := utf8.RuneCountInString(原始文本)
	if 长度 <= 取出数 {
		返回文本 = 原始文本
		return
	}
	开始位置 := 长度 - 取出数
	i := 0
	for _, v := range 原始文本 {
		if i >= 开始位置 {
			返回文本 = 返回文本 + string(v)
		}
		i++
	}
	return

}

func (类 *W文本) QZ取中间(原始文本, 开始文本, 结束文本 string) (结果 string) {
	文本 := 类.QY取右边(原始文本, 开始文本)
	结果 = 类.QZ取左边(文本, 结束文本)
	return
}

// 起始取出位置 按字符位置 重0开始
func (类 *W文本) QZ取中间_按字符数(原始文本 string, 起始取出位置, 取出数 int) (返回文本 string) {
	返回文本 = ""
	已取数量 := 0
	i := 0
	for _, v := range 原始文本 {
		if i >= 起始取出位置 {
			已取数量++
			if 已取数量 <= 取出数 {
				返回文本 = 返回文本 + string(v)
			}

		}
		i++
	}
	return

}
func (*W文本) QC取出现次数(原始文本, 寻找文本 string) (次数 int) {
	次数 = strings.Count(原始文本, 寻找文本)
	return
}

func (*W文本) QH取汉字(原始文本 string) string {
	var 正则 Z正则
	正则.C创建("[\u4e00-\u9fa5]+")
	列 := 正则.Q取匹配列表(原始文本)
	return 列.L连接到文本("")
}

// 通过 {1},{2},{3} 进行站为替换对应文本位置
func (*W文本) C创建文本(原始文本 string, 对应文本 ...any) (返回值 string) {
	返回值 = 创建文本(原始文本, 0, 对应文本...)
	return
}

func (*W文本) F分割文本(原始文本, 分割字符 string) (返回切片 []string) {
	if 原始文本 == "" {
		返回切片 = make([]string, 0)
		return
	}
	返回切片 = strings.Split(原始文本, 分割字符)
	return
}

func (*W文本) F分割文本_逐字分割(原始文本 string) (返回切片 []string) {
	if 原始文本 == "" {
		返回切片 = make([]string, 0)
		return
	}
	for _, v := range 原始文本 {
		返回切片 = append(返回切片, string(v))
	}
	return
}

func (*W文本) F分割文本_空白符(原始文本 string) (返回切片 []string) {
	返回切片 = strings.Fields(原始文本)
	return
}

func (*W文本) L连接文本_切片(原始文本 []string, 合并连接符 string) (结果 string) {
	结果 = strings.Join(原始文本, 合并连接符)
	return
}

// @W_文本_子文本替换
//
//	@替换次数 <0 或 大于存在数 为替换全部
//
// @从左往右边  true   重右到左 则填false
func (*W文本) T替换文本_有方向(原始文本, 被替换字符, 替换字符 string, 替换次数 int, 从左往右边 bool) (返回值 string) {
	存在数量 := strings.Count(原始文本, 被替换字符)
	if 存在数量 == 0 {
		return 原始文本
	}
	if 替换次数 < 0 || 替换次数 >= 存在数量 {
		返回值 = strings.Join(strings.Split(原始文本, 被替换字符), 替换字符)
		return
	}
	if 替换次数 > 0 {
		if !从左往右边 {
			返回值 = 原始文本
			for i := 0; i < 替换次数; i++ {
				位置 := strings.LastIndex(返回值, 被替换字符)
				返回值 = 返回值[:位置] + 替换字符 + 返回值[位置+len(被替换字符):]
			}
			return
		} else {
			返回值 = 原始文本
			for i := 0; i < 替换次数; i++ {
				位置 := strings.Index(返回值, 被替换字符)
				返回值 = 返回值[:位置] + 替换字符 + 返回值[位置+len(被替换字符):]
			}
			return

		}
	}
	return 原始文本
}

// @将字符串 原始文本 前n个不重叠  被替换字符 子串都替换为  替换字符 的新字符串
// @如果n<0会替换所有old子串。
func (*W文本) T替换文本(原始文本, 被替换字符, 替换字符 string, 替换次数 int) (返回值 string) {

	返回值 = strings.Replace(原始文本, 被替换字符, 替换字符, 替换次数)
	return
}
func (*W文本) P判断前缀(原始文本, 前缀文本 string) (返回值 bool) {
	返回值 = strings.HasPrefix(原始文本, 前缀文本)
	return
}
func (*W文本) P判断后缀(原始文本, 后缀文本 string) (返回值 bool) {
	返回值 = strings.HasSuffix(原始文本, 后缀文本)
	return
}
func (*W文本) P判断存在(原始文本, 寻找文本 string) (返回值 bool) {
	返回值 = strings.ContainsAny(原始文本, 寻找文本)
	return
}

// @判断字符串s是否包含unicode的码值r
func (*W文本) P判断存在_unicode(原始文本 string, 寻找文本 rune) (返回值 bool) {
	返回值 = strings.ContainsRune(原始文本, 寻找文本)
	return
}

// @判断字符串 原始文本 是否包含  寻找文本  字符串中的任意一个字符
func (*W文本) P判断包含(原始文本 string, 寻找文本 string) (返回值 bool) {
	返回值 = strings.ContainsAny(原始文本, 寻找文本)
	return
}

// @判断s和t两个UTF-8字符串是否相等，忽略大小写
func (*W文本) P判断相同_utf8(原始文本, 对比文本 string) (返回值 bool) {
	返回值 = strings.EqualFold(原始文本, 对比文本)
	return
}

/*
@ 按字典顺序比较a和b字符串的大小
@ 如果 a > b，返回一个大于 0 的数
@ 如果 a > b，如果 a == b，返回 0
@ 如果 a < b，返回一个小于 0 的数
*/
func (*W文本) P判断字典顺(原始文本, 对比文本 string) (返回值 int) {
	返回值 = strings.Compare(原始文本, 对比文本)
	return
}

func (*W文本) DX到小写(原始文本 string) (返回值 string) {
	返回值 = strings.ToLower(原始文本)
	return
}
func (*W文本) DD到大写(原始文本 string) (返回值 string) {
	返回值 = strings.ToTitle(原始文本)
	return
}

// @将字符串 原始文本 首尾包含在  条件字符 中的任一字符去掉
func (*W文本) S删首尾包含(原始文本, 条件字符 string) (返回值 string) {
	返回值 = strings.Trim(原始文本, 条件字符)
	return
}
func (*W文本) S删首包含(原始文本, 条件字符 string) (返回值 string) {
	返回值 = strings.TrimLeft(原始文本, 条件字符)
	return
}
func (*W文本) S删首文本(原始文本, 条件文本 string) (返回值 string) {
	返回值 = strings.TrimPrefix(原始文本, 条件文本)
	return
}
func (*W文本) S删尾包含(原始文本, 条件字符 string) (返回值 string) {
	返回值 = strings.TrimRight(原始文本, 条件字符)
	return
}
func (*W文本) S删尾文本(原始文本, 条件文本 string) (返回值 string) {
	返回值 = strings.TrimSuffix(原始文本, 条件文本)
	return
}
func (*W文本) S删首尾_空(原始文本 string) (返回值 string) {
	返回值 = strings.TrimSpace(原始文本)
	return
}

func (*W文本) QC去重复文本(原始文本 string) string {
	切片 := strings.Split(原始文本, "")
	返回文本 := ""
	for _, v := range 切片 {
		位置 := strings.Index(返回文本, v)
		if 位置 >= 0 {
			continue
		}
		返回文本 = 返回文本 + v
	}
	return 返回文本
}

func (*W文本) SF是否_是数字(原始文本 string) bool {
	var 正则 Z正则
	正则.C创建(`^-?\d+(\.\d+)?$`)
	return 正则.J校验(原始文本)
}

func (*W文本) SF是否_整数(原始文本 string) bool {
	var 正则 Z正则
	正则.C创建(`^-?\d+$`)
	return 正则.J校验(原始文本)
}

func (*W文本) SF是否_浮点数(原始文本 string) bool {
	var 正则 Z正则
	正则.C创建(`^-?\d+\.\d+$`)
	return 正则.J校验(原始文本)
}

func (*W文本) C插入文本到某字后(原生文本, 某字词, 插入文本 string) string {
	// 查找目标字在目标文本中的位置
	index := strings.Index(原生文本, 插入文本)
	if index == -1 {
		// 如果目标字未找到，返回原文本
		return 原生文本
	}

	// 将插入文本插入到目标字之后的位置
	return 原生文本[:index+len(插入文本)] + 某字词 + 原生文本[index+len(插入文本):]
}

func (*W文本) QW取文本长度_按字符数(原始文本 string) int {
	if 原始文本 == "" {
		return 0
	}
	return utf8.RuneCountInString(原始文本)

}
